package com.example.reactor.r2dbc;

import com.example.reactor.r2dbc.db.Customer;
import com.example.reactor.r2dbc.db.CustomerRepository;
import com.example.reactor.r2dbc.db.jdbc.JDBCService;
import com.example.reactor.r2dbc.db.nativeSQL.NativeSqlService;
import com.example.reactor.r2dbc.db.nativeSQL.RecordRowMapper;
import com.example.reactor.r2dbc.db.template.DynamicTableByTemplate;
import io.r2dbc.spi.Connection;
import io.r2dbc.spi.ConnectionFactory;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StopWatch;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;

import java.util.List;

/**
 * @author zpMeng
 * @since 6/16/2025
 */
@Slf4j
@RestController
@RequestMapping("r2dbc")
public class CustomerController {

    @Resource
    private CustomerRepository customerRepository;
    @Resource
    private DynamicTableByTemplate dynamicTableByTemplate;
    @Resource
    private ConnectionFactory connectionFactory;

    @Resource
    private NativeSqlService nativeSqlService;
    @Resource
    private JDBCService jdbcService;

    @GetMapping("default")
    public Flux<Customer> getCustomers() {
        return customerRepository.findByLastName("Bauer");
    }

    @GetMapping("byTemplate")
    public Flux<Customer> getCustomersByTemplate() {
        return dynamicTableByTemplate.findByFirstName("Ja");
    }

    @GetMapping("nativeSQL")
    public void getCustomersByNativeSQL(
            @RequestParam(required = false, defaultValue = "customer") String tableName) {
        String sql = "select * from DS_AGG_427_1 where node_id <= 10000";


        Flux
                .usingWhen(
                        connectionFactory.create(),
                        connection -> Flux
                                .from(connection.createStatement(sql).execute())
                                .flatMap(result -> result.map(new RecordRowMapper()))
                                .count(),
                        Connection::close
                )
                .blockLast();

    }

    @GetMapping("jdbc")
    public List<Customer> getCustomersByJDBC() {
        return jdbcService.getCustomersByJDBC();
    }
}
